#include "Node.h"
#include <iostream>
#include <stdio.h>
Node::Node()
{
	this -> number = 0;
	this -> next = NULL;
	this -> prev = NULL;
}
Node::Node(int x)
{
	this -> number = x;
	this -> next = NULL;
	this -> prev = NULL;
}
Node::~Node()
{
}
int Node::getNumber(void) const
{
	return this -> number;
}
Node* Node::getNext(void) const
{
	return this -> next;
}
Node* Node::getPrev(void) const
{
	return this -> prev;
}
void Node::setNext(Node *p)
{
	this -> next = p;
}
void Node::setPrev(Node *p)
{
	this -> prev = p;
}
std::istream& operator >> (std::istream &in, Node &N)
{
	in >> N.number;
	return in;
}
List::List()
{
	first = last = NULL;
}
void List::operator + (int n)
{
	Node *tmp = new Node(n);
	if (this -> first == NULL)
	{
		this -> first = tmp;
		this -> last = tmp;
	}
	else
	{
		tmp -> setPrev(this -> last);
		this -> last -> setNext(tmp);
		this -> last = tmp;
	}
}
void List::operator + (const Node &N)
{
	Node *tmp = new Node(N.getNumber());
	if (this -> first == NULL)
	{
		this -> first = tmp;
		this -> last = tmp;
	}
	else
	{
		tmp -> setPrev(this -> last);
		this -> last -> setNext(tmp);
		this -> last = tmp;
	}
}
void List::Print(void) const
{
	Node *tmp = this -> first;
	if (tmp == NULL)
		printf("Empty list.");
	else
		for (; tmp != NULL; tmp = tmp -> getNext())
			printf("%d ", tmp -> getNumber());
}
bool List::operator == (const List &L)
{
	Node 	*tmp1 = this -> first, *tmp2 = L.first;
	bool ok = true;
	while (tmp1 != NULL && tmp2 != NULL)
	{
		if (tmp1 -> getNumber() != tmp2 -> getNumber())
		{	
			ok = false;
			break;
		}	
		tmp1 = tmp1 -> getNext();
		tmp2 = tmp2 -> getNext();
	}
	return ok;
}
bool List::operator == (const List *L)
{
	Node 	*tmp1 = this -> first, *tmp2 = L -> first;
	bool ok = true;
	while (tmp1 != NULL && tmp2 != NULL)
	{
		if (tmp1 -> getNumber() != tmp2 -> getNumber())
		{	
			ok = false;
			break;
		}	
		tmp1 = tmp1 -> getNext();
		tmp2 = tmp2 -> getNext();
	}
	return ok;
}
bool List::operator != (const List &L)
{
	Node 	*tmp1 = this -> first, *tmp2 = L.first;
	bool ok = true;
	while (tmp1 != NULL && tmp2 != NULL)
	{
		if (tmp1 -> getNumber() != tmp2 -> getNumber())
		{	
			ok = false;
			break;
		}	
		tmp1 = tmp1 -> getNext();
		tmp2 = tmp2 -> getNext();
	}
	return !ok;
}
bool List::operator != (const List *L)
{
	Node 	*tmp1 = this -> first, *tmp2 = L -> first;
	bool ok = true;
	while (tmp1 != NULL && tmp2 != NULL)
	{
		if (tmp1 -> getNumber() != tmp2 -> getNumber())
		{	
			ok = false;
			break;
		}	
		tmp1 = tmp1 -> getNext();
		tmp2 = tmp2 -> getNext();
	}
	return !ok;
}
void List::Concatenate(List &L)
{
	this -> last -> setNext(L.first);
	L.first -> setPrev(this -> last);
}
void List::Reunite(const List &L)
{
	Node *temp, *tmp1, *tmp2 = L.first;
	bool ok;
	for (; tmp2 != NULL; tmp2 = tmp2 -> getNext())
	{
		ok = true;
		for (tmp1 = this -> first; tmp1 != NULL; tmp1 = tmp1 -> getNext())
			if (tmp2 -> getNumber() == tmp1 -> getNumber())
			{
				ok = false;
				break;
			}
		if (ok)
		{
			temp = new Node(tmp2 -> getNumber());
			temp -> setPrev(this -> last);
			this -> last -> setNext(temp);
			this -> last = temp;
		}
	}		
}
List* List::Intersect(const List &L)
{
	List *T = new List();
	Node *tmp1, *tmp2;
	for (tmp1 = this -> first; tmp1 != NULL; tmp1 = tmp1 -> getNext())
		for (tmp2 = L.first; tmp2 != NULL; tmp2 = tmp2 -> getNext())
			if (tmp1 -> getNumber() == tmp2 -> getNumber())
				*T + tmp1 -> getNumber();
	return T;
}
using namespace std;
int main()
{
	int i = 0;
	Node N;
	List L1, L2, *L3;
	while (i < 5)
	{
		cin >> N;
		L1 + N;
		++i;
	}
	i = 0;
	while (i < 5)
	{
		cin >> N;
		L2 + N;
		++i;
	}
	printf("L1 = ");
	L1.Print();
	printf("L2 = ");
	L2.Print();
	printf("\n");
	L3 = L1.Intersect(L2);
	printf("L3 = ");
	(*L3).Print();
	return 0;
}